package de.tum.in.far.threedui.general.collision;

import java.util.Enumeration;
import java.util.Vector;

import javax.media.j3d.Behavior;
import javax.media.j3d.BoundingSphere;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.Group;
import javax.media.j3d.Node;
import javax.media.j3d.WakeupCondition;
import javax.media.j3d.WakeupCriterion;
import javax.media.j3d.WakeupOnCollisionEntry;
import javax.media.j3d.WakeupOnCollisionExit;
import javax.media.j3d.WakeupOr;
import javax.vecmath.Point3d;

public class CollisionDetector extends Behavior {

	Vector<CollisionListener> collisionListeners;
	BranchGroup targetBG;
	WakeupCondition condition;

	public CollisionDetector( BranchGroup tg) {
		this.targetBG = tg;
		this.collisionListeners = new Vector<CollisionListener>();
//		tg.setCapability(Group.ALLOW_COLLISION_BOUNDS_READ);
//		tg.setCapability(Node.ALLOW_PICKABLE_READ);
//		tg.setCapability(Node.ALLOW_PICKABLE_WRITE);
//		tg.setCapability(Node.ALLOW_COLLIDABLE_WRITE);
//		tg.setCapability(Node.ENABLE_COLLISION_REPORTING);
//		tg.setCapability(Node.ENABLE_PICK_REPORTING);
//		tg.setCapability(Group.ALLOW_CHILDREN_WRITE);
//		tg.setCapability(Group.ALLOW_CHILDREN_READ);
//		tg.setCapability(Group.ALLOW_CHILDREN_EXTEND);
		
//		tg.addChild(this);
	}

	public void register(CollisionListener cl) {
		this.collisionListeners.add(cl);
	}

	@Override
	public void initialize() {

		System.out.println("COLLISION DETECTOR INSTANTIATED !!");
		setSchedulingBounds(new BoundingSphere(new Point3d(0, 0, 0), 50f));

		condition = new WakeupOr(new WakeupCriterion[] {
				new WakeupOnCollisionEntry(this.targetBG),
				new WakeupOnCollisionExit(this.targetBG) });
		wakeupOn(condition);
	}

	@Override
	public void processStimulus(Enumeration arg0) {

		WakeupCriterion crit = (WakeupCriterion) arg0.nextElement();

		if (crit instanceof WakeupOnCollisionEntry) {
			WakeupOnCollisionEntry woc = (WakeupOnCollisionEntry) crit;
//			Node triggeingObject = woc.getTriggeringPath().getObject();
//			System.out.println("COLLISION IN :["
//					+ ((WakeupOnCollisionEntry) crit).getTriggeringPath()
//							.getObject().getClass().getName() + "]");

			for (CollisionListener cl : this.collisionListeners)
				cl.onCollision(this.targetBG, woc.getTriggeringPath());

		} else {
			System.out.println("COLLISION EVENT :" + crit.getClass().getName());
		}

		wakeupOn(condition);

	}

}
